Network applications that handle client-server type communications are increasingly becoming more sophisticated. A typical client-server communication involves a client sending a request to a server, and the server returning a response to the client. The server is typically composed of several logical components that handle the client request. Before a response is generated in response to a client request, the client request is often handled in some way by the several logical components of the server.
In a typical application, the server accesses a data source to retrieve information for the client in response to the client request. Each logical component of the server performs functions on the client request before forwarding the client request to the intended data source or to another component. For example, one of the server components may be a JAVA program that performs some computation, queries the data source for select data, performs some more computations, and then returns a result to the client. Other components of the server may handle the communication sequentially, to perform additional computations or make more database queries.
Some of the server components may also handle a response to the client request. For example, in addition to forwarding the client request to the data source, a server component may also forward a response from the data source back to the client. The component may also perform computations and/or make additional queries in response to receiving the response to the client request.
In some configurations, devices that handle the client communication include a load-balancing device and a server machine. The server machine is selected from a group of server machines by the load-balancing device. The selected server machine and load-balancer are used to exchange communications between a client and a data source, such as a database. The server machines forward the client communication from the load-balancing device to the intended database. The database may correspond to a web server or other machine that provides access to information for the client communication.
The devices that handle a client communication combine to provide multiple logical components that process the client communication before it is forwarded to the database. For example, the logical components may be tiered within the server machine(s) in order to distribute processes used for handling the client communication. These tiered components handle the client communications in a sequential manner. The result is that the client communication is sequentially processed by multiple components residing on different machines before being received by the intended database.
Often, a client communication will fail to reach its destination. A client communication may fail because the destination is inaccessible at the time the client communication is signaled to it. A client communication may also fail because one of the components that handles the client communication fails.
The components in many client-server systems are configured to retry failed client communications at the point where the failure is detected. In multi-tiered configurations, the failure detection is propagated to all of the logical components that individually handle the client communication. The result is that multiple components in one server machine individually attempt to retry failed client communications. Furthermore, the multi-tiered configuration causes some components to retry sending the failed client communication multiple times before the failure is reported back to the client. Most of these extra attempts to retry failed client communications are futile.
For example, assume that a server machine provides a communication path that includes a first application 830, a second application 840 and a server application 820, as shown in FIG. 8. The communication path is used to couple a client 810 to a destination. In this example, the destination is a data source 850. A conventional system having no designated retry component would employ second application 840, first application 830 and server application 820 to repeatedly retry a failed client communication. If, for example, the failure occurs when second application 840 attempts to contact data source 850, then the conventional system would provide that second application 840 retries the client communication, then indicates the failure to first application 830. The first application then retries the failed client communication. If data source 850 is still not available to second application 840, then the retry by first application 830 is followed by another retry by second application 840. The server component 820 is notified of the failure after second application 840 retries twice, and first application 830 retries once. If server component 820 retries, second application 840 may retry two more times, and first application 830 may retry again. The result is that client 810 waits a relatively long period before being notified of the failed client communication.
In some existing systems, when a failure occurs in an environment with redundant components, the environment will reconfigure itself such that subsequent requests are sent to another surviving instance. Thus, retrying the request will usually succeed, but another machine and additional resources are needed. For example, if a database server crashes, the environment will reconfigure itself such that subsequent requests will go to another server machine. The selection of another server machine may be made by the load balancer, often after internal components of the original server machine fail.
Based on the foregoing, it is clearly desirable to provide techniques for handling communication failures without the waste that results from multiple components in a communication path performing retry operations in response to a failure that occurs along the communication path.